package com.cn.remote;

import com.cn.coder.MessageDecoder;
import com.cn.coder.MessageEncoder;
import com.cn.common.BrokerCluster;
import com.cn.common.RemotResponseType;
import com.cn.common.RemoteResponse;
import com.cn.common.TopicStore;
import com.cn.msg.Message;
import com.cn.rpc.RpcProxy;
import com.cn.util.GsonUtil;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.handler.timeout.IdleStateHandler;

import java.nio.charset.Charset;
import java.util.concurrent.TimeUnit;

public class RemoteClientHandler extends ChannelInitializer<SocketChannel> {

    private RemoteClient remoteClient;

    public RemoteClientHandler(RemoteClient remoteClient) {
        this.remoteClient = remoteClient;
    }

    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        //如果消息是自定义类型，那么用以下处理器
        ch.pipeline().addLast(new MessageEncoder());//编码器
        ch.pipeline().addLast(new MessageDecoder());//解码器
        ch.pipeline().addLast(new IdleStateHandler(0, 0, 3, TimeUnit.SECONDS));//心跳设置
        ch.pipeline().addLast(new ClientConnectManageHandler(this.remoteClient));//心跳处理器
        ch.pipeline().addLast(new ClientHandler(this.remoteClient));//业务处理器
    }
}

/**
 * 心跳超时处理
 */
class ClientConnectManageHandler extends ChannelDuplexHandler {

    private RemoteClient remoteClient;

    public ClientConnectManageHandler(RemoteClient remoteClient) {
        this.remoteClient = remoteClient;
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleState state = ((IdleStateEvent) evt).state();
            if (state.equals(IdleState.ALL_IDLE)) {
                Message message = new Message();
                message.setType((byte) 1);//这里需要区分是 心跳包类型
                message.setFlag((byte) 2);
                message.setByteBodys("心跳".getBytes("UTF-8"));
                ctx.writeAndFlush(message);
            }
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }
}

/**
 * 自定义消息处理器
 */
class ClientHandler extends ChannelInboundHandlerAdapter {

    private RemoteClient remoteClient;

    public ClientHandler(RemoteClient remoteClient) {
        this.remoteClient = remoteClient;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {

    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        RemoteResponse.handle(ctx, msg, RemotResponseType.CLIENT, this.remoteClient.getDefaultMessageStore());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        this.remoteClient.setOk(false);
        System.out.println("与服务端断开连接了！");
//        System.out.println(cause.getMessage());
        cause.printStackTrace();
        ctx.close();
    }


}